﻿/**
//  frmMainMenu.cs
//  Marquee Moment
//  Copyright 2011 Systematix Technocrates. All rights reserved.
**/
using System;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using MarqueeMoment.Entities;
using MarqueeMoment.Forms;
using System.IO;
using NLog;

namespace MarqueeMoment
{
    public partial class frmMainMenu : Form
    {
        #region User defined Variables

        private static Logger logger = LogManager.GetCurrentClassLogger();
        public static UserEntity user = null;
        private System.ComponentModel.BackgroundWorker backgroundWorker;

        #endregion User defined Variables

        #region Constructor

        public frmMainMenu()
        {
            logger.Info("On frmMainMenu()");
            InitializeComponent();
            initializeBackgroundWorker();
            InitializeValues();
        }
        
        #endregion Constructor

        #region BackgroundWorker

        private void initializeBackgroundWorker()
        {
            backgroundWorker = new BackgroundWorker();
            backgroundWorker.WorkerReportsProgress = true;
            backgroundWorker.WorkerSupportsCancellation = true;

        }

        // This event handler is where the time-consuming work is done.
        private void backgroundWorker_DoWork_Login(object sender, DoWorkEventArgs e)
        {
            logger.Info("On backgroundWorker_DoWork_Login(object sender, DoWorkEventArgs e)");
            BackgroundWorker worker = sender as BackgroundWorker;
            if (worker.CancellationPending == true)
            {
                e.Cancel = true;
            }
            else
            {
                // Perform a time consuming operation and report progress.
                doLogin(worker);
            }

        }

        private void doLogin(BackgroundWorker worker)
        {
            user = UserEntity.Select(txtUname.Text.Trim(), PasswordEncodeDecode.Base64Encode(txtPassword.Text.Trim()));
        }

        // This event handler deals with the results of the background operation.
        private void backgroundWorker_RunWorkerLoginCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            logger.Info("On backgroundWorker_RunWorkerLoginCompleted(object sender, RunWorkerCompletedEventArgs e)");
            LoginCompleted();
            //Remove login events from background worker.
            backgroundWorker.DoWork -= backgroundWorker_DoWork_Login;
            backgroundWorker.RunWorkerCompleted -= backgroundWorker_RunWorkerLoginCompleted;

        }

        #endregion BackgroundWorker

        #region User Defined Methods

        /// <summary>
        /// Show login result
        /// </summary>
        private void LoginCompleted()
        {
            logger.Info("On LoginCompleted()");
            btnLogin.Visible = true;
            picBoxSpinner.Visible = false;
            //if (Connection.conn == null)
            //{
            if (user != null)
            {
                if (user.UserType == true)
                {
                    btnAdmin.Visible = true;
                }

                pnlMenu.Visible = true;
                pnlLogin.Visible = false;

                for (int count = 0; count < pnlList.Controls.Count; count++)
                {
                    ScheduleControl listUserControl = pnlList.Controls[count] as ScheduleControl;
                    if (listUserControl != null)
                    {
                        listUserControl.btnDelete.Visible = true;
                        listUserControl.btnReschedule.Visible = true;
                    }
                }

            }
            else
            {
                logger.Info("On LoginCompleted() , bad login with Username:"+ txtUname.Text + " and Password " + txtPassword.Text);
                Dialogs.Error("Wrong User Name Or Password!");
                txtUname.Focus();
            }
            //}
        }

        /// <summary>
        /// To delete selected shedule record
        /// </summary>
        private DialogResult DeleteScheduleGT(Int32 scheduleId)
        {
            logger.Info("On DeleteScheduleGT(Int32 scheduleId), with scheduleId:" + scheduleId.ToString());
            frmDialog customBox = new frmDialog("Warning", "Are you sure to delete?");
            if (customBox.ShowDialog() == System.Windows.Forms.DialogResult.Yes)
            {
                try
                {
                    ScheduleEntity schedule = new ScheduleEntity();
                    schedule.ScheduleId = scheduleId;

                    schedule = ScheduleEntity.Select(schedule.ScheduleId);
                    if (schedule != null)
                    {
                        ImageEntity imageValue = ImageEntity.Select(schedule.ImageId);
                        if (imageValue != null)
                        {
                            logger.Info("On DeleteScheduleGT(), deleting imageId:" + imageValue.ImageId.ToString());
                            ImageEntity.Delete(imageValue.ImageId);

                            logger.Info("On DeleteScheduleGT(), deleted imageId:" + imageValue.ImageId.ToString() + " , now deleting image from network location");
                            //Delete image from network resource
                            Common.DeleteFromNetworkResource(schedule);
                            logger.Info("On DeleteScheduleGT(), image deleted from network location");
            
                        }
                    }
                    return System.Windows.Forms.DialogResult.Yes;
                }
                catch (Exception exc)
                {
                    logger.Error(exc.StackTrace);
                    Dialogs.Error("Error on deleting schedule image, see log file for more details");
                }
            }
            return System.Windows.Forms.DialogResult.No;


        }

        /// <summary>
        /// To reschedule selected record
        /// </summary>
        private void ReScheduleGT(Int32 scheduleId)
        {
            logger.Info("On ReScheduleGT(Int32 scheduleId) with scheduleId:" + scheduleId.ToString());
            try
            {
                ScheduleEntity schedule = new ScheduleEntity();
                schedule.ScheduleId = scheduleId;

                schedule = ScheduleEntity.Select(schedule.ScheduleId);
                if (schedule != null)
                {
                    ImageEntity imageValue = ImageEntity.Select(schedule.ImageId);
                    if (imageValue != null)
                    {
                        if (!Directory.Exists(Common.composedPhotoDirPath))
                            Directory.CreateDirectory(Common.composedPhotoDirPath);

                        logger.Info("On ReScheduleGT() , creating image from db");
                        FileStream FS1 = new FileStream(MarqueeMoment.Entities.Common.composedPhotoPath(), FileMode.Create);
                        byte[] blob = imageValue.ImageData;
                        FS1.Write(blob, 0, blob.Length);
                        FS1.Close();
                        FS1 = null;
                        logger.Info("On ReScheduleGT() , image created at " + MarqueeMoment.Entities.Common.composedPhotoPath());
                        
                        frmScheduleScreen obSchedule = new frmScheduleScreen(schedule);
                        obSchedule.ShowDialog();
                    }
                }
            }
            catch (Exception exc)
            {
                logger.Error(exc.StackTrace);
                Dialogs.Error("Error on Reshudling image, see log file for more details");
            }


        }

        //Called by user controller
        public void buttonDeleteClick(object sender, EventArgs e, Int32 scheduleId)
        {
            logger.Info("On buttonDeleteClick(object sender, EventArgs e, Int32 scheduleId) with scheduleId:" + scheduleId.ToString());
            if (DeleteScheduleGT(scheduleId) == System.Windows.Forms.DialogResult.Yes)
                RefreshGTList();
        }

        //Called by user controller
        public void buttonRescheduleClick(object sender, EventArgs e, Int32 scheduleId)
        {
            logger.Info("On buttonRescheduleClick(object sender, EventArgs e, Int32 scheduleId) with scheduleId:" + scheduleId.ToString());
            ReScheduleGT(scheduleId);
        }

        private void RefreshGTList()
        {
            logger.Info("On RefreshGTList()");
            DataTable dtGTSchedule = null; ;
            DataSet dataset = ScheduleEntity.SelectAllScheduleWithImage();
            if (dataset != null && dataset.Tables.Count > 0)
            {
                if (pnlList.Controls.Count > 0)
                    pnlList.Controls.Clear();
                                
                dtGTSchedule = dataset.Tables[0];
                ScheduleControl userControl;
                Int32 yPOS = 20;

                for (int count = 0; count < dtGTSchedule.Rows.Count; count++)
                {
                    userControl = new ScheduleControl((Int32)dtGTSchedule.Rows[count]["ScheduleId"]);

                    DateTime dtScheduletime = (DateTime)dtGTSchedule.Rows[count]["ScheduleTime"];

                    if (user != null)
                    {
                        userControl.btnDelete.Visible = true;
                        userControl.btnReschedule.Visible = true;
                    }
                    else
                    {
                        userControl.btnDelete.Visible = false;
                        userControl.btnReschedule.Visible = false;

                    }
                    userControl.lblTime.Text = dtScheduletime.ToLongTimeString();
                    if (dtGTSchedule.Rows.Count > 3)
                        userControl.Width = pnlList.Width - 22;
                    else
                        userControl.Width = pnlList.Width - 2;

                    if (userControl.picBox.Image != null)
                        userControl.picBox.Image.Dispose();

                    byte[] blob = (byte[])dtGTSchedule.Rows[count]["ImageData"];
                    MemoryStream ms = new MemoryStream(blob);
                    Image returnImage = Image.FromStream(ms);

                    userControl.picBox.Image = returnImage;
                    userControl.picBox.SizeMode = PictureBoxSizeMode.StretchImage;
                    userControl.picBox.Refresh();

                    userControl.Location = new System.Drawing.Point(2, yPOS);
                    pnlList.Controls.Add(userControl);

                    yPOS = yPOS + userControl.Height + 10;
                }
            }

        }

        private bool validateUserName(String userName)
        {
            logger.Info("On validateUserName(String userName) with userName:" + userName);
            if (String.IsNullOrEmpty(userName))
            {
                errorProviderLogin.SetError(txtUname, "Please enter your Name");
                txtUname.Focus();
                return false;
            }
            else
            {
                errorProviderLogin.Clear();
                return true;
            }
        }

        private bool validatePassword(String password)
        {
            logger.Info("On validatePassword(String password) with password:" + password);
            if (String.IsNullOrEmpty(password))
            {
                errorProviderLogin.SetError(txtPassword, "Please enter Password");
              //  txtPassword.Focus();
                return false;
            }
            else
            {
                errorProviderLogin.Clear();
                return true;
            }
        }

        /// <summary>
        /// To Show Time on Time Box
        /// </summary>
        private void ShowTime()
        {
            String currentTime = String.Empty;
            var timeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
            currentTime = TimeZoneInfo.ConvertTime(DateTime.Now, timeZone).ToLongTimeString();
            lblPM.Text = currentTime.Substring(currentTime.Length - 2);
            currentTime = currentTime.Substring(0, currentTime.Length - 3);

            lblT8.Text = currentTime.Substring(currentTime.Length - 1);
            lblT7.Text = currentTime.Substring(currentTime.Length - 2, 1);
            lblT6.Text = currentTime.Substring(currentTime.Length - 3, 1);
            lblT5.Text = currentTime.Substring(currentTime.Length - 4, 1);
            lblT4.Text = currentTime.Substring(currentTime.Length - 5, 1);
            lblT3.Text = currentTime.Substring(currentTime.Length - 6, 1);
            lblT2.Text = currentTime.Substring(currentTime.Length - 7, 1);

            if (currentTime.Length == 7)
                lblT1.Text = String.Empty;
            else
                lblT1.Text = currentTime.Substring(currentTime.Length - 8, 1);
        }

        /// <summary>
        /// To Initialize Values
        /// </summary>
        private void InitializeValues()
        {
            logger.Info("On InitializeValues()");
            Common.clearTempPhotosDir();
            ShowTime();

            Image spinnerImage = Image.FromFile(Common.spinnerImagePath);
            picBoxSpinner.Image = spinnerImage;
        }

        /// <summary>
        /// Set form visiblity and enable mode of timer
        /// </summary>
        /// <param name="status"> boolean value type</param>
        private void updateFormStatus(bool status)
        {
            timerMainmenu.Enabled = status;
            timerMinute.Enabled = status;
        }

        #endregion User Defined Methods

        #region System Events

        private void btnLogin_Click(object sender, EventArgs e)
        {
            logger.Info("On btnLogin_Click(object sender, EventArgs e)");
            String password = txtPassword.Text.Trim();
            String userName = txtUname.Text.Trim();

            logger.Info("Clicked on login, entering with username:" + userName + "and password:" + password);
            try
            {
                if ((!validateUserName(userName)) || (!validatePassword(password)))
                {
                    return;
                }

                #region Default Hardcoded User Login Section
                if ((String.Compare(userName, "MMadmin", true) == 0) && (String.Compare(password, "MMadmin", false) == 0))
                {
                    user = new UserEntity();
                    user.UserId = 0;
                    user.UserName = userName;
                    user.Password = password;
                    user.UserType = true;
                    LoginCompleted();
                    return;
                }
                #endregion Default Hardcoded User Login Section

                if (backgroundWorker.IsBusy != true)
                {
                    backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork_Login);
                    backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker_RunWorkerLoginCompleted);
                    // Start the asynchronous operation.
                    backgroundWorker.RunWorkerAsync();
                    btnLogin.Visible = false;
                    picBoxSpinner.Visible = true;


                }
                else if (backgroundWorker.IsBusy)
                {
                    Dialogs.Exclamation("Already in progress");
                }
            }
            catch (Exception exc)
            {
                logger.Error(exc.StackTrace);
            }
        }

        private void btnLogout_Click(object sender, EventArgs e)
        {
            logger.Info("On btnLogout_Click(object sender, EventArgs e)");
            for (int count = 0; count < pnlList.Controls.Count; count++)
            {
                ScheduleControl listUserControl = pnlList.Controls[count] as ScheduleControl;
                if (listUserControl != null)
                {
                    listUserControl.btnDelete.Visible = false;
                    listUserControl.btnReschedule.Visible = false;
                }
            }
            pnlLogin.Visible = true;
            pnlMenu.Visible = false;
            btnAdmin.Visible = false;
            txtPassword.Text = string.Empty;
            txtUname.Text = string.Empty;
            txtUname.Focus();
        }

        private void btnAdmin_Click(object sender, EventArgs e)
        {
            logger.Info("On btnAdmin_Click(object sender, EventArgs e)");
            updateFormStatus(false);
            frmAdmin obAdminForm = new frmAdmin();
            obAdminForm.ShowDialog();
            updateFormStatus(true);
        }

        private void btnImport_Click(object sender, EventArgs e)
        {
            logger.Info("On btnImport_Click(object sender, EventArgs e)");
            try
            {
                if (Common.importPhoto() == DialogResult.OK)
                {
                    updateFormStatus(false);
                    frmComposeMessage obComposeMessage = new frmComposeMessage();
                    obComposeMessage.ShowDialog();
                    updateFormStatus(true);
                }

            }
            catch (Exception exc)
            {
                logger.Error(exc.StackTrace);
                Dialogs.Error("The process cannot access the file because it is being used by another process.");
            }


        }

        private void timerMainmenu_Tick_1(object sender, EventArgs e)
        {
            ShowTime();
        }

        private void txtUname_Validating(object sender, CancelEventArgs e)
        {
            validateUserName(txtUname.Text.Trim());
        }

        private void txtPassword_Validating(object sender, CancelEventArgs e)
        {
            validatePassword(txtPassword.Text.Trim());
        }

        private void btnStartNewSession_Click(object sender, EventArgs e)
        {
            logger.Info("On btnStartNewSession_Click(object sender, EventArgs e)");
            updateFormStatus(false);
            frmTakePhoto obTakePhoto = new frmTakePhoto(true);
            if (obTakePhoto.isCameraDetected)
                obTakePhoto.ShowDialog();

            updateFormStatus(true);
            
        }

        private void frmMainMenu_Activated(object sender, EventArgs e)
        {
            logger.Info("On frmMainMenu_Activated(object sender, EventArgs e)");
            Common.clearTempPhotosDir();
            RefreshGTList();
        }

        private void btnArchives_Click(object sender, EventArgs e)
        {
            logger.Info("On btnArchives_Click(object sender, EventArgs e)");
            updateFormStatus(false);
            frmArchive archive = new frmArchive();
            archive.ShowDialog();
            updateFormStatus(true);
        }

        private void timerMinute_Tick(object sender, EventArgs e)
        {
            RefreshGTList();
        }

        private void frmMainMenu_FormClosing(object sender, FormClosingEventArgs e)
        {
            logger.Info("On frmMainMenu_FormClosing(object sender, FormClosingEventArgs e)");
            Common.clearTempPhotosDir();
            System.Environment.Exit(0);
        }


        #endregion System Events



    }
}
